package com.ruoyi.task.service.impl;


import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessStatus;
import com.ruoyi.common.enums.OperatorType;
import com.ruoyi.common.exception.base.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ExceptionUtil;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.http.HttpUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService;
import com.ruoyi.task.domain.SceneCameraParamsInfo;
import com.ruoyi.task.domain.StreamPictureParams;
import com.ruoyi.task.domain.StreamPictureResult;
import com.ruoyi.task.domain.TaskDetail;
import com.ruoyi.task.service.IHaoYunService;
import com.ruoyi.task.service.IMainTaskService;
import com.ruoyi.task.service.ISceneParamsInfoService;
import com.ruoyi.task.service.ISubBankServerConfigService;
import com.ruoyi.task.service.ITaskDetailService;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class MainTaskServiceImpl implements IMainTaskService {

    @Autowired
    private ITaskDetailService taskDetailService;

    @Autowired
    private IHaoYunService haoYunService;

    @Autowired
    private ISubBankServerConfigService subBankServerConfigService;

    @Value("${agentServerIp:http://10.223.7.21:9000}")
    private String agentServerIp;

    @Autowired
    private ISceneParamsInfoService sceneParamsInfoService;

    @Autowired
    private ISysOperLogService sysOperLogService;

    @Override
    public void processCollectMainTask() {
        try {
            // 查询待处理的任务
            TaskDetail taskDetail = new TaskDetail();
            taskDetail.setTaskStatus("00");
            taskDetail.setTaskType("1");
            List<TaskDetail> taskDetailList = taskDetailService.queryCollectTaskDetail(taskDetail);

            for (TaskDetail detail : taskDetailList) {
                collectTaskDetail(detail);
            }
        } catch (Exception e) {
            log.error("processCollectMainTask error ", e);
            throw new RuntimeException(e);
        }
    }

    /**
     * 采集任务
     *
     * @param taskDetail
     */
    private void collectTaskDetail(TaskDetail taskDetail) {
        TaskDetail taskDetailUpdate = new TaskDetail();
        try {
            log.info("collectTaskDetail begin, id = {}", taskDetail.getTaskDetailId());
            taskDetailUpdate.setTaskDetailId(taskDetail.getTaskDetailId());

            // 判断白天不采集 TODO

            // 生成任务编号
            String taskId = String.format("%s-%s-%s-(%s-%s)", taskDetail.getBankCode(),
                    taskDetail.getCameraId(), generateTaskId(),
                    DateUtils.convertToCompactFormat(taskDetail.getStartTime()),
                    DateUtils.convertToCompactFormat(taskDetail.getStartEnd()));

            taskDetail.setTaskId(taskId);

            // 修改数据库状态为采集中
            //任务状态（00-初始化 01-视频采集中 02-视频采集完成 03-视频采集失败 04-视频分析中 05-视频分析完成 06-视频分析失败）
            taskDetailUpdate.setTaskStatus("01");
            taskDetailUpdate.setTaskId(taskId);
            taskDetailService.updateTaskDetail(taskDetailUpdate);

            // 文件序号
            int seq = 0;

            // 成功量
            int success = 0;

            String dir = null;

            long runStartTime = System.currentTimeMillis();

            String collectTime = taskDetail.getStartTime();
            while (!DateUtils.isAfter(collectTime, taskDetail.getStartEnd())) {
                seq++;
                log.info("collectTaskDetail taskId = {}, seq = {}", taskId, seq);
                // 采集图片
                String image = getImage(collectTime, taskDetail, 5);

                collectTime = DateUtils.addSeconds(collectTime, DateUtils.YYYY_MM_DD_HH_MM_SS,
                        taskDetail.getSecondMerge());
                if (image == null) {
                    log.warn("collectTaskDetail continue taskId = {}, seq = {}", taskId, seq);
                    continue;
                }
                success++;

                String fileName = String.format("%s_%06d_%s.jpg", taskId, seq,
                        DateUtils.convertToCompactFormat(collectTime));

                // 上传图片
                String filePath = uploadImage(image, fileName, taskDetail.getTaskId());
                if (StringUtils.isBlank(dir)) {
                    dir = StringUtils.replace(filePath, fileName, "");
                }

            }

            saveOperLog(taskId, seq, success, runStartTime);

            if (StringUtils.isBlank(dir)) {
                log.info("collectTaskDetail no image, taskId = {}", taskId);
                taskDetailUpdate.setTaskStatus("03");
                taskDetailUpdate.setMsg(StringUtils.isBlank(taskDetail.getMsg()) ? "浩云下载失败"
                        : taskDetail.getMsg());
                taskDetailService.updateTaskDetail(taskDetailUpdate);
                return;
            }
            taskDetailUpdate.setTaskStatus("02");
            taskDetailService.updateTaskDetail(taskDetailUpdate);

            sendAgent(taskDetail, dir);
        } catch (Exception e) {
            log.error("collectTaskDetail error: ", e);
            taskDetailUpdate.setTaskStatus("03");
            taskDetailUpdate.setMsg("系统异常：" + e.getMessage());
            taskDetailService.updateTaskDetail(taskDetailUpdate);
        }
        log.info("collectTaskDetail end, id = {}", taskDetail.getTaskDetailId());
    }

    /**
     * 保存日志
     *
     * @param taskId
     * @param total
     * @param success
     * @param startTime
     */
    private void saveOperLog(String taskId, int total, int success, Long startTime) {
        try {
            SysOperLog operLog = new SysOperLog();
            operLog.setStatus(total == success ? BusinessStatus.SUCCESS.ordinal()
                    : BusinessStatus.FAIL.ordinal());
            // 请求的地址
            operLog.setOperIp("127.0.0.1");
            operLog.setOperUrl("/video/getHistoricalStreamPictureSync");

            // 设置方法名称
            operLog.setMethod(
                    "com.ruoyi.task.service.impl.MainTaskServiceImpl.collectTaskDetail()");
            // 设置请求方式
            operLog.setRequestMethod("POST");

            // 设置消耗时间
            operLog.setCostTime(System.currentTimeMillis() - startTime);

            operLog.setJsonResult(
                    String.format("{\"taskId\":\"%s\",\"total\":%s,\"success\":%s}", taskId, total,
                            success));
            operLog.setTitle("总行采集任务");

            operLog.setOperatorType(1);
            operLog.setBusinessType(10);
            operLog.setOperLocation("内网IP");
            operLog.setOperName("system");

            // 保存数据库
            sysOperLogService.insertOperlog(operLog);
        } catch (Exception e) {
            log.error("saveOperLog error :", e);
        }

    }

    /**
     * 发送agent分析任务
     *
     * @param taskDetail
     * @param dir
     */
    private void sendAgent(TaskDetail taskDetail, String dir) {
        TaskDetail taskDetailUpdate = new TaskDetail();
        taskDetailUpdate.setTaskDetailId(taskDetail.getTaskDetailId());
        try {
            log.info("sendAgent begin, taskId = {}", taskDetail.getTaskId());

            String url = agentServerIp + "/api/v1/common/params_check";
//            String url = agentServerIp + "/api/v1/common/picture_check";


            // 推送至agent分析
            String[] sceneTypes = StringUtils.split(taskDetail.getScenariosType(), ",");

            Map<String, String> params = new HashMap<>();
            params.put("content_path", dir);
            params.put("picture_parent_path", dir);
            params.put("task_id", taskDetail.getTaskId());
            params.put("second", taskDetail.getSecondMerge().toString());
            params.put("start_time", taskDetail.getStartTime());
            params.put("end_time", taskDetail.getStartEnd());
            params.put("camera_id", taskDetail.getCameraId());
            params.put("type", "capture");

            int count = 0;
            StringBuilder msg = new StringBuilder();
            for (String type : sceneTypes) {
                params.put("scene_id", type);
                log.info("sendAgent start, taskId = {}, sceneId = {}", taskDetail.getTaskId(),
                        type);

                // 查询场景参数配置
                SceneCameraParamsInfo sceneCameraParams = new SceneCameraParamsInfo();
                sceneCameraParams.setScenariosType(type);
                sceneCameraParams.setTaskType("1");
                sceneCameraParams.setCameraId(taskDetail.getCameraId());
                sceneCameraParams.setBankCode(taskDetail.getBankCode());
                Map<String, String> configMap = sceneParamsInfoService.querySceneParamsConfig(
                        sceneCameraParams);
                if (configMap != null) {
                    params.putAll(configMap);
                }

                String param = JSONObject.toJSONString(params);
                String rspStr = HttpUtils.sendPost(url, param, MediaType.APPLICATION_JSON_VALUE, 3);
                log.info("sendAgent end, taskId = {}, sceneId = {}, end msg = {}",
                        taskDetail.getTaskId(), type, rspStr);
                JSONObject jsonObject = JSONObject.parseObject(rspStr);
                if (jsonObject == null) {
                    msg.append("请求agent分析失败");
                } else if (StringUtils.equals("1",
                        jsonObject.getString("responseCode")) ||
                        jsonObject.getInteger("statusCode") == 422) {
                    log.warn("sendAgent end error, taskId = {}, sceneId = {}",
                            taskDetail.getTaskId(), type);
                    JSONObject data = jsonObject.getJSONObject("responseData");
                    if (data != null) {
                        msg.append(data.getString("msg"));
                    } else if (StringUtils.isNotBlank(jsonObject.getString("msg"))) {
                        msg.append(jsonObject.getString("msg"));
                    }
                } else if (StringUtils.equals("0",
                        jsonObject.getString("responseCode"))) {
                    count++;
                }

            }
            taskDetailUpdate.setMsg(msg.toString());
            if (count == 0) {
                taskDetailUpdate.setTaskStatus("06");
            } else {
                taskDetailUpdate.setTaskStatus("04");
            }

        } catch (Exception e) {
            taskDetailUpdate.setTaskStatus("06");
            taskDetailUpdate.setMsg("系统异常：" + e.getMessage());
            log.error("sendAgent error ", e);
        }
        // 修改采集任务状态
        taskDetailService.updateTaskDetail(taskDetailUpdate);
        log.info("sendAgent end, taskId = {}", taskDetail.getTaskId());
    }

    /**
     * 获取图片
     *
     * @param collectTime
     * @param taskDetail
     * @param requestTime 请求次数
     * @return
     */
    private String getImage(String collectTime, TaskDetail taskDetail, int requestTime) {
        StreamPictureParams params = new StreamPictureParams();
        try {
            requestTime--;
            if (requestTime < 0) {
                return null;
            }
            log.info("getImage taskId = {}, count = {}", taskDetail.getTaskId(), requestTime);

            // 采集图片
            params.setCameraId(taskDetail.getCameraId());
            params.setRequestTime(collectTime);
            params.setSerialNo(UUID.generateSerialNumber());
            log.info("getImage begin taskId = {}, serialNo = {}", taskDetail.getTaskId(),
                    params.getSerialNo());

            StreamPictureResult result = haoYunService.historicalStreamPictureSync(params);
            if (result != null) {
                log.info("getImage success taskId = {}", taskDetail.getTaskId());
                return result.getScenneImage();
            } else {
                return getImage(collectTime, taskDetail, requestTime);
            }
        } catch (BaseException e) {
            taskDetail.setMsg(e.getMessage());
            if (StringUtils.equals("500000", e.getCode())) {
                return getImage(collectTime, taskDetail, requestTime);
            }
        } catch (Exception e) {
            taskDetail.setMsg("系统异常" + e.getMessage());
            log.error("getImage error: ", e);
        }
        log.warn("getImage error taskId = {}, serialNo = {}", taskDetail.getTaskId(),
                params.getSerialNo());
        return null;
    }

    /**
     * 上传图片
     *
     * @param image
     * @param fileName
     * @param taskId
     * @return
     */
    private String uploadImage(String image, String fileName, String taskId) {
        try {
            log.info("uploadImage begin fileName = {}", fileName);
            Map<String, String> map = new HashMap<>();
            map.put("base64", image);
            map.put("file_name", fileName);
            map.put("task_id", taskId);

            // 上传图片
            String params = JSON.toJSONString(map);
            Map<String, String> headers = new HashMap<>();
            headers.put("Content-Type", MediaType.APPLICATION_JSON_VALUE);

            String url = agentServerIp + "/api/v1/file/image_upload";

            String rspStr = HttpUtils.sendPost(url, params, headers, 10000);
            log.info("uploadImage end fileName = {}, result = {}", fileName, rspStr);
            if (StringUtils.isBlank(rspStr)) {
                return null;
            }
            JSONObject jsonObject = JSON.parseObject(rspStr);
            if (StringUtils.equals(jsonObject.getString("responseCode"), "0")) {
                return jsonObject.getJSONObject("responseData").getString("image_dir");
            } else {
                log.warn("uploadImage error: {}", jsonObject.getString("responseMsg"));
            }
        } catch (Exception e) {
            log.error("uploadImage error: ", e);
        }
        return null;
    }


    /**
     * 生成任务编号 格式：yyyyMMdd-XXXXXXXXX (日期+9位序列号)
     *
     * @return 任务编号
     */
    private String generateTaskId() {
        String datePart = DateUtils.dateTime(); // 获取当前日期的yyyyMMdd格式
        String sequencePart = String.format("%09d",
                DateUtils.generateTimestampSequence()); // 格式化为9位数字
        return datePart + "-" + sequencePart;
    }
}
